﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenESSOConfigurator.BusinessLayer;
using OpenESSOConfigurator.BusinessLayer.Atoms;
using OpenESSOConfigurator.BusinessLayer.Stores;
using OpenESSOConfigurator.PresentationLayer.EventBroker;
using OpenESSOConfigurator.PresentationLayer.PresentationModels;
using OpenESSOConfigurator.PresentationLayer.EventBroker.Handlers;

namespace OpenESSOConfigurator.PresentationLayer.UserControls
{
    public partial class ItemTreeView : UserControl,IView
    {
        private TreeNode applicationsTreeNode;
        private TreeNode csgTreeNode;
        private TreeNode passwordPoliciesTreeNode;
        private TreeNode configurationStoresTreeNode;
        private TreeNode credentialStoresTreeNode;
        private String visibleTreeNodeTag;

        #region Private API
        private void InitializeAtomTreeNode()
        {
            ApplicationsTreeNode = new TreeNode("Applications",0,0);
            ApplicationsTreeNode.Nodes.Add(new TreeNode("Windows Applications",1,1));
            ApplicationsTreeNode.Nodes.Add(new TreeNode("Web Applications",2,2));
            CSGTreeNode = new TreeNode("Credential Sharing Groups",4,4);
            PasswordPoliciesTreeNode = new TreeNode("Password Policies",5,5);
            ConfigurationStoresTreeNode = new TreeNode("Configuration Stores", 5, 5);
            CredentialStoresTreeNode = new TreeNode("Credential Stores", 5, 5);
        }
        #endregion

        #region Getter Setter
        public TreeNode ApplicationsTreeNode
        {
            get { return applicationsTreeNode; }
            set { applicationsTreeNode = value; }
        }
        public TreeNode CSGTreeNode
        {
            get { return csgTreeNode; }
            set { csgTreeNode = value; }
        }
        public TreeNode PasswordPoliciesTreeNode
        {
            get { return passwordPoliciesTreeNode; }
            set { passwordPoliciesTreeNode = value; }
        }

        public TreeNode ConfigurationStoresTreeNode
        {
            get { return configurationStoresTreeNode; }
            set { configurationStoresTreeNode = value; }
        }
        public TreeNode CredentialStoresTreeNode
        {
            get { return credentialStoresTreeNode; }
            set { credentialStoresTreeNode = value; }
        }
        
        #endregion

        public ItemTreeView()
        {
            InitializeComponent();
            InitializeAtomTreeNode();
        }

        #region Public API
        public TreeView TreeView1
        {
            set { treeView1 = value; }
            get { return treeView1; }
        }
        public ImageList ImageItemList
        {
            set { imageItemList1 = value; }
            get { return imageItemList1; }
        }

        // This delegate enables asynchronous calls for setting
        // the configuration on the tree view.
        delegate void SetOpenESSOConfigurationCallback(OpenESSOConfiguration conf);
        private void SetOpenESSOConfiguration(OpenESSOConfiguration conf)
        {
            // InvokeRequired required compares the thread ID of the
			// calling thread to the thread ID of the creating thread.
			// If these threads are different, it returns true.
            if (this.InvokeRequired)
            {
                SetOpenESSOConfigurationCallback d = new SetOpenESSOConfigurationCallback(SetOpenESSOConfiguration);
                this.Invoke(d, new object[] { conf });
            }
            else
            {

                InitializeAtomTreeNode();
                foreach (WinApplication winApplication in conf.Applications.WinApplications)
                {
                    TreeNode tn = new TreeNode(winApplication.Name + " version: " + winApplication.Version);
                    tn.Tag = winApplication;
                    tn.ImageIndex = 1;
                    foreach (WinForm winForm in winApplication.WinForms)
                    {
                        TreeNode tnf = new TreeNode(winForm.Name);
                        tnf.Tag = winForm;
                        tnf.ImageIndex = 0;
                        tn.Nodes.Add(tnf);
                    }
                    ApplicationsTreeNode.Nodes[0].Nodes.Add(tn);
                }
                
                foreach (WebApplication webApplication in conf.Applications.WebApplications)
                {
                    TreeNode tn = new TreeNode(webApplication.Name + " version: " + webApplication.Version);
                    tn.Tag = webApplication;
                    tn.ImageIndex = 2;
                    foreach (WebForm webForm in webApplication.WebForms)
                    {
                        TreeNode tnf = new TreeNode(webForm.Name);
                        tnf.Tag = webForm;
                        tnf.ImageIndex = 0;
                        tn.Nodes.Add(tnf);
                    }
                    ApplicationsTreeNode.Nodes[1].Nodes.Add(tn);

                }
                //load csg config
                foreach (CredentialSharingGroup csg in conf.CredentialSharingGroups)
                {
                    TreeNode tn = new TreeNode(csg.Name + " version: " + csg.Version);
                    tn.Tag = csg;
                    tn.ImageIndex = 4;
                    CSGTreeNode.Nodes.Add(tn);
                }
                //load password policy config
                foreach (PasswordPolicy p in conf.PasswordPolicies)
                {
                    TreeNode tn = new TreeNode(p.Name + " version: " + p.Version);
                    tn.Tag = p;
                    tn.ImageIndex = 5;
                    PasswordPoliciesTreeNode.Nodes.Add(tn);
                }
                //load conf store config
                foreach (ConfigurationStore cs in conf.ConfigurationStores)
                {
                    TreeNode tn = new TreeNode(cs.Name);
                    tn.Tag = cs;
                    tn.ImageIndex = 5;
                    ConfigurationStoresTreeNode.Nodes.Add(tn);
                }
                ShowTreeNode(visibleTreeNodeTag);
            }
        }

        [EventSubscription("topic://ItemTreePresentationModel/ConfigurationChanged", typeof(Publisher))]
        public void UpdateTreeView(object sender,EventArgs e)
        {
            SetOpenESSOConfiguration((OpenESSOConfiguration)sender);
        }

        [EventSubscription("topic://LeftSpinePresentationModel/SelectedButtonChanged", typeof(Publisher))]
        public void LoadTreeNode(object sender, EventArgs e)
        {
            ToolStripButton tlsBtn = (ToolStripButton)sender;
            String tag = tlsBtn.Tag.ToString();
            this.visibleTreeNodeTag = tag;
            ShowTreeNode(visibleTreeNodeTag);
        }
        #endregion

        private void ShowTreeNode(String tag)
        {
            this.TreeView1.BeginUpdate();
            this.TreeView1.Nodes.Clear();
            switch (tag)
            {
                case "applications":
                    this.TreeView1.Nodes.Add(ApplicationsTreeNode);
                    break;
                case "csg":
                    this.TreeView1.Nodes.Add(CSGTreeNode);
                    break;
                case "passwordpolicies":
                    this.TreeView1.Nodes.Add(PasswordPoliciesTreeNode);
                    break;
                case "configurationstores":
                    this.TreeView1.Nodes.Add(ConfigurationStoresTreeNode);
                    break;
                case "credentialstores":
                    this.TreeView1.Nodes.Add(CredentialStoresTreeNode);
                    break;
                default:
                    this.TreeView1.Nodes.Add(ApplicationsTreeNode);
                    break;
            }
            //this.TreeView1.ExpandAll();
            this.TreeView1.EndUpdate();
        }
        
        private void AfterTreeNode_Selected(object sender, TreeViewEventArgs e)
        {
            TreeNode selectedNode=((TreeView)sender).SelectedNode;
            if (selectedNode.Tag != null)
            {
                if (selectedNode.Tag.GetType().Equals(typeof(WinApplication)))
                    ItemTreePresentationModel.Instance.SelectedWinApplication = (WinApplication)selectedNode.Tag;
                if (selectedNode.Tag.GetType().Equals(typeof(WebApplication)))
                    ItemTreePresentationModel.Instance.SelectedWebApplication = (WebApplication)selectedNode.Tag;
                // winform selected
                if (selectedNode.Tag.GetType().Equals(typeof(WinForm)))
                    ItemTreePresentationModel.Instance.SelectedWinForm = (WinForm)selectedNode.Tag;
                // webForm seleted
                if (selectedNode.Tag.GetType().Equals(typeof(WebForm)))
                    ItemTreePresentationModel.Instance.SelectedWebForm = (WebForm)selectedNode.Tag;
                // csg
                if (selectedNode.Tag.GetType().Equals(typeof(CredentialSharingGroup)))
                    ItemTreePresentationModel.Instance.SelectedCSG = (CredentialSharingGroup)selectedNode.Tag;
                // passwordPolicy
                if (selectedNode.Tag.GetType().Equals(typeof(PasswordPolicy)))
                    ItemTreePresentationModel.Instance.SelectedPasswordPolicy = (PasswordPolicy)selectedNode.Tag;   
                // configuration stores
                if (selectedNode.Tag.GetType().Equals(typeof(ConfigurationStore)))
                    ItemTreePresentationModel.Instance.SelectedConfigurationStore = (ConfigurationStore)selectedNode.Tag;   
            }
        }

        private void ItemTreeView_Load(object sender, EventArgs e)
        {
            LeftSpinePresentationModel.Instance.RegisterView(this);
            ItemTreePresentationModel.Instance.RegisterView(this);
        }
    }
}
